package net.zigin.nhi.could.waste.service.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import net.zigin.commons.util.NumberUtil;
import net.zigin.commons.util.ParamsMapUtil;
import net.zigin.commons.util.ReflectUtil;
import net.zigin.commons.util.StringUtil;
import net.zigin.nhi.could.waste.aop.LoginAspect;
import net.zigin.nhi.could.waste.dao.BaseMapper;
import net.zigin.nhi.could.waste.dao.StatisticMapper;
import net.zigin.nhi.could.waste.dao.SysUserHospitalMapper;
import net.zigin.nhi.could.waste.dao.WarnBaseMapper;
import net.zigin.nhi.could.waste.dao.WasteBaseMapper;
import net.zigin.nhi.could.waste.dao.WasteBoxMapper;
import net.zigin.nhi.could.waste.dao.WasteBoxRecordMapper;
import net.zigin.nhi.could.waste.dto.PageDto;
import net.zigin.nhi.could.waste.dto.WasteBaseDto;
import net.zigin.nhi.could.waste.dto.WasteCountDto;
import net.zigin.nhi.could.waste.exception.EpiCloudException;
import net.zigin.nhi.could.waste.model.WasteBase;
import net.zigin.nhi.could.waste.model.WasteBox;
import net.zigin.nhi.could.waste.model.WasteBoxRecord;
import net.zigin.nhi.could.waste.service.WasteBaseService;
import net.zigin.nhi.could.waste.util.EncryptDataUtil;
import net.zigin.nhi.could.waste.util.ExcelUtil;
import net.zigin.nhi.could.waste.vo.TokenInfoBo;
import net.zigin.nhi.could.waste.vo.WasteBaseVo;
import net.zigin.nhi.could.waste.vo.WasteBoxRecordVo;
import net.zigin.nhi.could.waste.vo.WasteBoxVo;
import net.zigin.nhi.could.waste.vo.WasteCount2Vo;
import net.zigin.nhi.could.waste.vo.WasteCountVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*#################################################################*
# 说明:以下代码通过哲勤代码生成工具自动生成    
# 工具:GeneratorCode
# 作者:mgw1986                                                  
# 生成时间:2021-9-20 17:17:58                                               
##################################################################*/


/**
 * WasteBase服务实现类
 *
 * @author mgw1986
 * @version V1.0
 * @ClassName: WasteBaseServiceImpl
 * @date 2021-9-20 17:17:58
 */
@Service
public class WasteBaseServiceImpl extends AbstractServiceImpl<WasteBase, String> implements WasteBaseService {
    @Autowired
    private WasteBaseMapper wasteBaseMapper;
    @Autowired
    private SysUserHospitalMapper sysUserHospitalMapper;
    @Autowired
    private WarnBaseMapper warnBaseMapper;
    @Autowired
    private WasteBoxRecordMapper wasteBoxRecordMapper;
    @Autowired
    private WasteBoxMapper wasteBoxMapper;
    @Autowired
    private StatisticMapper statisticMapper;

    @Override
    public BaseMapper<WasteBase, String> getMapper() {
        return wasteBaseMapper;
    }

    @Override
    public List<WasteCountVo> eachMonth() {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        return wasteBaseMapper.eachMonth(hospitalBaseId);
    }

    @Override
    public List<WasteCountVo> weekClassify() {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        return wasteBaseMapper.weekClassify(hospitalBaseId);
    }

    @Override
    public List<WasteCountVo> fifteenDepart(WasteCountDto wasteCountDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        Map<String, Object> paramMap = ParamsMapUtil.getInstance()
                .addParam("year", wasteCountDto.getYear())
                .addParam("month", wasteCountDto.getMonth())
                .addParam("hospitalBaseId", hospitalBaseId);
        return wasteBaseMapper.fifteenDepart(paramMap);
    }

    @Override
    public List<WasteBaseVo> getList(WasteBaseDto wasteBaseDto) {
        // 入参 classify status hospitalPlace hospitalDepart createTime key(code boxCode userName)
        // 出参 code depart place classify collectUser handUser revicer status box
        Map<String, Object> paramMap = getWasteBaseParam(wasteBaseDto);
        List<WasteBaseVo> list = wasteBaseMapper.getInfoPageByCondition(paramMap);
        if (list.isEmpty()) {
            return new ArrayList<>();
        }
        list.forEach(wasteBaseVo -> {
            wasteBaseVo.setContent(generateQrCode(wasteBaseVo.getId()));
        });
        return list;
    }

    @Override
    public Integer getCount(WasteBaseDto wasteBaseDto) {
        Map<String, Object> paramMap = getWasteBaseParam(wasteBaseDto);
        return wasteBaseMapper.getCountByCondition(paramMap);
    }

    @Override
    public List<WasteCountVo> statusReport(WasteCountDto wasteCountDto) {
        List<WasteCountVo> result = new ArrayList<>();
        result.add(new WasteCountVo("do_collect"));
        result.add(new WasteCountVo("in_depot"));
        result.add(new WasteCountVo("out_depot"));
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        wasteCountDto.setHospitalBaseId(hospitalBaseId);
        List<WasteCountVo> wasteCountVos = wasteBaseMapper.statusReport(wasteCountDto);
        wasteCountVos.forEach(wasteCountVo1 -> {
            result.forEach(wasteCountVo -> {
                if (wasteCountVo.getStatus().equals(wasteCountVo1.getStatus())) {
                    wasteCountVo.setWeight(wasteCountVo1.getWeight());
                    wasteCountVo.setCount(wasteCountVo1.getCount());
                }
            });
        });
        return result;
    }

    @Override
    public List<WasteCountVo> classifyReport(WasteCountDto wasteCountDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        wasteCountDto.setHospitalBaseId(hospitalBaseId);
        return wasteBaseMapper.classifyReport(wasteCountDto);
    }

    @Override
    public List<WasteCountVo> classifyDepartReport(WasteCountDto wasteCountDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        if (StringUtil.isNullOrEmpty(hospitalBaseId)) {
            return wasteBaseMapper.classifyHospitalReport(wasteCountDto);
        } else {
            wasteCountDto.setHospitalBaseId(hospitalBaseId);
            return wasteBaseMapper.classifyDepartReport(wasteCountDto);
        }
    }

    @Override
    public List<WasteBaseVo> collectList(PageDto pageDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        Map<String, Object> paramMap = ParamsMapUtil.getInstance()
                .addParam("hospitalBaseId", hospitalBaseId)
                .addParam("pageIndex", pageDto.getPageIndex())
                .addParam("pageSize", pageDto.getPageIndex());
        List<WasteBase> wasteBases = wasteBaseMapper.collectList(paramMap);
        if (wasteBases.isEmpty()) {
            return new ArrayList<>();
        } else {
            return ReflectUtil.copyProperties(wasteBases, WasteBaseVo.class);
        }
    }

    @Override
    public Map<String, Object> situation() {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        Float weightSum = wasteBaseMapper.weightSum(hospitalBaseId);
        Integer warnCount = warnBaseMapper.warnCount(hospitalBaseId);
        Integer staffCount = statisticMapper.staffCount(hospitalBaseId);
        Integer revicerCount = statisticMapper.revicerCount(hospitalBaseId);
        Map<String, Object> result = new HashMap<>();
        if (StringUtil.isNullOrEmpty(hospitalBaseId)) {
            Integer hospitalCount = statisticMapper.hospitalBaseCount();
            result.put("hospitalCount", hospitalCount);
        }
        result.put("weightSum", weightSum);
        result.put("warnCount", warnCount);
        result.put("collectStaffCount", staffCount);
        result.put("handStaffCount", revicerCount);
        return result;
    }

    @Override
    public void exportList(WasteCountDto wasteCountDto, HttpServletResponse response) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        List<WasteCountVo> list = this.classifyDepartReport(wasteCountDto);
        if (list.isEmpty()) {
            throw new EpiCloudException("当前报表无数据！");
        }
        try {
            // 不带标题
            if (StringUtil.isNullOrEmpty(hospitalBaseId)) {
                List<WasteCount2Vo> wasteCount2Vos = ReflectUtil.copyProperties(list, WasteCount2Vo.class);
                ExcelUtil.exportExcel(wasteCount2Vos, WasteCount2Vo.class, "医废报表", new ExportParams(), response);
            } else {
                ExcelUtil.exportExcel(list, WasteCountVo.class, "医废报表", new ExportParams(), response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, Object> warnInfoByBoxRecordId(String boxRecordId) {
        List<WasteBase> wasteBases = wasteBaseMapper.listByWasteBoxRecordId(boxRecordId);
        Float collectWeight = wasteBases.stream().map(WasteBase::getWeight).reduce(Float::sum).orElse(0f);
        WasteBoxRecord wasteBoxRecord = wasteBoxRecordMapper.selectByPrimaryKey(boxRecordId);
        WasteBox wasteBox = wasteBoxMapper.selectByPrimaryKey(wasteBoxRecord.getWasteBoxId());
        Map<String, Object> result = new HashMap<>();
        result.put("wasteBox", ReflectUtil.copyProperties(wasteBox, WasteBoxVo.class));
        result.put("wasteBoxRecord", ReflectUtil.copyProperties(wasteBoxRecord, WasteBoxRecordVo.class));
        result.put("collectWeight", NumberUtil.scaleFloat(collectWeight + wasteBox.getWeight(), 2));
        if (result.isEmpty()) {
            result.put("wasteBases", new ArrayList<>());
        } else {
            result.put("wasteBases", ReflectUtil.copyProperties(wasteBases, WasteBaseVo.class));
        }
        return result;
    }

    @Override
    public void deleteById(String id) {
        // 获取token信息
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String loginName = tokenInfo.getLoginName();
        // 更新医废基础数据为删除状态
        WasteBase wasteBase = new WasteBase();
        wasteBase.setId(id);
        wasteBase.setIsDelete(1);
        wasteBase.setModifyUser(loginName);
        wasteBase.setModifyTime(new Date());
        wasteBaseMapper.updateByPrimaryKeySelective(wasteBase);
    }

    private Map<String, Object> getWasteBaseParam(WasteBaseDto wasteBaseDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        if (!StringUtil.isNullOrEmpty(hospitalBaseId) && StringUtil.isNullOrEmpty(wasteBaseDto.getHospitalBaseId())) {
            wasteBaseDto.setHospitalBaseId(hospitalBaseId);
        }
        return ParamsMapUtil.getInstance()
                .addParam("wasteClassifyCode", wasteBaseDto.getWasteClassifyCode())
                .addParam("status", wasteBaseDto.getStatus())
                .addParam("hospitalBaseId", wasteBaseDto.getHospitalBaseId())
                .addParam("hospitalPlaceId", wasteBaseDto.getHospitalPlaceId())
                .addParam("hospitalDepartId", wasteBaseDto.getHospitalDepartId())
                .addParam("keyWord", wasteBaseDto.getKeyWord())
                .addParam("createTimeStart", wasteBaseDto.getCreateTimeStart())
                .addParam("createTimeEnd", wasteBaseDto.getCreateTimeEnd())
                .addParam("pageIndex", wasteBaseDto.getPageIndex())
                .addParam("pageSize", wasteBaseDto.getPageSize())
                .addParam("isDelete", wasteBaseDto.getIsDelete());
    }

    private String generateQrCode(String id) {
        WasteBase wasteBase = wasteBaseMapper.selectByPrimaryKey(id);
        if (wasteBase == null) {
            throw new EpiCloudException("医废不存在");
        }
        return EncryptDataUtil.encryptData("wasteBase", wasteBase.getId());
    }
}